Spring validation 分组校验用法

Spring validation 分组校验用法

Wangjie Lv2

前言

在使用 Java Bean Validation 进行参数校验的时候,很多场景下的一个Req实体都是同时满足多个业务,但是可能在不同的业务场景下,参数校验有细微的差别。例如在新增用户和编辑用户的场景下,UserReq实体相同,但是编辑的时候用户ID是必填的。如果想要新增用户和编辑用户共用一个UserReq实体,就只能在id属性上去掉@NotNull注解,在编辑方法上手动判断,这样实际上比较麻烦,也不够优雅。

1
2
3
4
5
6
7
8
public class UserReq {
private Long id;
@NotEmpty(message="name 不能为空")
private String name;
@NotNull(message="age 不能为空")
private int age;
...
}
1
2
3
4
5
6
7
8
9
10
11
12
public class UserController{
public R create(@RequestBody @Valid UserReq userReq){
...
}
public R edit(@RequestBody @Valid UserReq userReq){
// 手动判断id
if(userReq.getId() == null){
throw new ServiceException(...)
}
...
}
}

如果能给id字段上打一个记号,标识出id字段只需要编辑时校验,新增的时候忽视掉就好了。

实现

实际上,@NotEmpty、@NotNull … 注解上有一个属性,叫做groups,用于指定一个验证分组。它允许你对同一个对象应用不同的验证规则,具体规则可以根据上下文的不同而有所不同。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(NotNull.List.class)
@Documented
@Constraint(
validatedBy = {}
)
public @interface NotNull {
String message() default "{javax.validation.constraints.NotNull.message}";

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface List {
NotNull[] value();
}
}

于是我们可以定义不同的验证分组接口,用于标识不同的验证场景。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
public interface ValidGroup {

interface InsertGroup {

}
interface UpdateGroup {

}

interface DeleteGroup {

}
}

然后在Req实体的属性上标注出场景

1
2
3
4
5
6
7
8
9
public class UserReq {
@NotNull(message="id不能为空", groups = {UpdateGroup.class})
private Long id;
@NotEmpty(message="name不能为空", groups = {InsertGroup.class, UpdateGroup.class})
private String name;
@NotNull(message="age不能为空", groups = {InsertGroup.class, UpdateGroup.class})
private int age;
...
}

然后在Controller接口方法上制定验证的分组规则

1
2
3
4
5
6
7
8
public class UserController{
public R create(@RequestBody @Validated(ValidGroup.InsertGroup.class) UserReq userReq){
...
}
public R edit(@RequestBody @Validated(ValidGroup.UpdateGroup.class) UserReq userReq){
...
}
}

这样就实现参数的优雅校验了。

  • Title: Spring validation 分组校验用法
  • Author: Wangjie
  • Created at : 2024-11-19 15:25:28
  • Updated at : 2024-11-19 19:54:34
  • Link: https://wj0410.github.io/2024/11/19/Spring validation 分组校验用法/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments
On this page
Spring validation 分组校验用法